package com.zw.rpc.client.impl;

import com.zw.rpc.Peer;
import com.zw.rpc.client.TransportSelector;
import com.zw.rpc.common.utils.ReflectionUtils;
import com.zw.rpc.transport.TransportClient;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * @author zw
 */
@Slf4j
public class RandomTransportSelector implements TransportSelector {

    private List<TransportClient> clients;

    public RandomTransportSelector() {
        this.clients = new ArrayList<>();
    }

    @Override
    public synchronized void init(List<Peer> peers, int count, Class<? extends TransportClient> clazz) {

        count = Math.max(count, 1);
        int finalCount = count;
        peers.forEach(peer -> {
            for (int i = 0; i < finalCount; i++) {
                TransportClient client = ReflectionUtils.newInstance(clazz);
                client.connect(peer);
                clients.add(client);
                log.info("connected server : {}", peer);
            }
        });
    }

    @Override
    public synchronized TransportClient select() {
        return clients.remove(new Random().nextInt(clients.size()));
    }

    @Override
    public synchronized void release(TransportClient client) {
        clients.add(client);
    }

    @Override
    public synchronized void close() {
        clients.forEach(TransportClient::close);
        clients.clear();
    }
}
